# -*- coding: utf-8 -*-
import random

import fcntl

from RunQuant.__main__ import run
import pandas as pd
import sys
import traceback
from Database.models import UpQuantBktestSumInfo
from Database.models import UpQuantStrategyContex
from Database.models import UpQuantTradeinfo
import Database.models as models
import json
import csv
import redis
import datetime
import time
import paging
import os


def getTotalInfo(info, results_df, startTime, endTime, init_cash):
    series = results_df.iloc[-1]
    info.runtime = 4
    info.initcash = init_cash
    info.begintime = pd.Timestamp(startTime)
    info.endtime = pd.Timestamp(endTime)
    info.totalreturn = series.total_returns
    info.benchmark = series.benchmark_total_returns
    info.alpha = series.alpha
    info.beta = series.beta
    info.sharpe = series.sharpe
    info.inforatio = series.information_rate
    info.sortino = series.sortino
    info.infomationratio = series.information_rate
    info.volatility = series.volatility
    info.maxdrewdown = series.max_drawdown
    info.trackingerror = series.tracking_error
    info.downsiderisk = series.downside_risk
    info.myannualreturn = series.annualized_returns
    info.benchmarkannualreturn = series.benchmark_annualized_returns


def isNiforNan(object):
    import numpy as np
    if np.isinf(object):
        return 0
    if np.isnan(object):
        return 0
    return object


def saveUpQuantBktestSumInfo(bktestSumInfo):
    temp = UpQuantBktestSumInfo.objects.filter(strategyid=bktestSumInfo.strategyid,
                                               versionid=bktestSumInfo.versionid)
    temp.delete()
    # print object_bt.values()
    object_bt = UpQuantBktestSumInfo()
    object_bt.strategyid = bktestSumInfo.strategyid
    object_bt.versionid = bktestSumInfo.versionid
    object_bt.runtime = bktestSumInfo.runtime
    object_bt.initcash = bktestSumInfo.initcash
    object_bt.begintime = bktestSumInfo.begintime
    object_bt.endtime = bktestSumInfo.endtime
    object_bt.totalreturn = isNiforNan(bktestSumInfo.totalreturn)
    object_bt.benchmark = isNiforNan(bktestSumInfo.benchmark)
    object_bt.alpha = isNiforNan(bktestSumInfo.alpha)
    object_bt.beta = isNiforNan(bktestSumInfo.beta)
    object_bt.sharpe = isNiforNan(bktestSumInfo.sharpe)
    object_bt.inforatio = isNiforNan(bktestSumInfo.inforatio)
    object_bt.sortino = isNiforNan(bktestSumInfo.sortino)
    object_bt.benchmarkannualreturn = isNiforNan(bktestSumInfo.benchmarkannualreturn)
    object_bt.myannualreturn = isNiforNan(bktestSumInfo.myannualreturn)
    object_bt.volatility = isNiforNan(bktestSumInfo.volatility)
    object_bt.maxdrewdown = isNiforNan(bktestSumInfo.maxdrewdown)
    object_bt.trackingerror = isNiforNan(bktestSumInfo.trackingerror)
    object_bt.downsiderisk = isNiforNan(bktestSumInfo.downsiderisk)
    # object_bt.createtime = bktestSumInfo.createtime
    object_bt.save()


def saveUpQuantContext(bktestSumInfo, codecontext, startTime, endTime, init_cash):
    temp = UpQuantStrategyContex.objects.filter(strategyid=bktestSumInfo.strategyid, versionid=bktestSumInfo.versionid)
    temp.delete()
    quantContext = UpQuantStrategyContex()
    quantContext.strategyid = bktestSumInfo.strategyid
    quantContext.versionid = bktestSumInfo.versionid
    quantContext.context = codecontext
    quantContext.begindate = str(startTime).replace('/', '-')
    quantContext.enddate = str(endTime).replace('/', '-')
    quantContext.initcash = init_cash
    cur_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    quantContext.createtime = cur_time
    quantContext.save()


def saveUpQuantTradeInfo(bktestSumInfo, results_df):
    quantinfo = UpQuantTradeinfo.objects.filter(strategyid=bktestSumInfo.strategyid, versionid=bktestSumInfo.versionid)
    quantinfo.delete()
    for tradeset in results_df["trades"]:
        for trade in tradeset:
            tradeinfo = UpQuantTradeinfo()
            tradeinfo.strategyid = bktestSumInfo.strategyid
            tradeinfo.versionid = bktestSumInfo.versionid
            tradeinfo.orderid = trade.order_id
            tradeinfo.ordertime = trade.date
            tradeinfo.orderdate = trade.date
            tradeinfo.stockcode = trade.order_book_id
            tradeinfo.stockname = trade.order_book_name
            tradeinfo.price = trade.price
            tradeinfo.ordercount = trade.amount
            tradeinfo.commission = trade.commission
            tradeinfo.totalcost = tradeinfo.commission + trade.tax + tradeinfo.price * tradeinfo.ordercount
            tradeinfo.orderstate = 0
            if (tradeinfo.ordercount < 0):
                tradeinfo.orderstate = -1
            else:
                tradeinfo.orderstate = 1
            tradeinfo.tax = trade.tax

            tradeinfo.save()


def saveUPTradeLogInfo(filename, results_df):
    fsock = open(filename, 'w')
    # 为了避免用户连续点击操作，频繁打开相同的此文件，所以对此文件加锁
    fcntl.flock(fsock, fcntl.LOCK_EX)
    f_position = open(filename + '.position', 'w')
    # 为了避免用户连续点击操作，频繁打开相同的此文件，所以对此文件加锁
    fcntl.flock(f_position, fcntl.LOCK_EX)
    f_total = open(filename + '.total', 'w')
    fcntl.flock(f_total, fcntl.LOCK_EX)
    if fsock is None:
        return
        # total_returns,annualized_returns,benchmark_total_returns,alpha,beta,sharpe,sortino,information_rate,volatility,max_drawdown,downside_risk\n
        return
    # total_returns,annualized_returns,benchmark_total_returns,alpha,beta,sharpe,sortino,information_rate,volatility,max_drawdown,downside_risk,positions\n
    for iter in results_df.index:
        log = str(iter) + ','
        log += str(results_df.loc[iter, 'total_returns']) + ','
        log += str(results_df.loc[iter, 'annualized_returns']) + ','
        log += str(results_df.loc[iter, 'benchmark_total_returns']) + ','
        log += str(results_df.loc[iter, 'alpha']) + ','
        log += str(results_df.loc[iter, 'beta']) + ','
        log += str(results_df.loc[iter, 'sharpe']) + ','
        log += str(results_df.loc[iter, 'sortino']) + ','
        log += str(results_df.loc[iter, 'information_rate']) + ','
        log += str(results_df.loc[iter, 'volatility']) + ','
        log += str(results_df.loc[iter, 'max_drawdown']) + ','
        log += str(results_df.loc[iter, 'downside_risk']) + '\n'
        fsock.write(log)
        position = results_df.loc[iter, 'positions']
        for d, x in position.items():
            log = str(iter) + ','
            log += str(d) + ','
            log += str(x.market_value) + ','
            log += str(x.quantity) + ','
            log += str(results_df.loc[iter, 'total_commission'] + results_df.loc[iter, 'total_tax']) + ','
            log += str(x.price_daily) + ','
            log += str(x.market_value - x.bought_value - results_df.loc[iter, 'total_commission'] + results_df.loc[
                iter, 'total_tax']) + ','
            log += str(x.book_name) + '\n'
            f_position.write(log)

        log = str(iter) + ','
        log += str(results_df.loc[iter, 'portfolio_value']) + ','
        log += str(results_df.loc[iter, 'total_commission'] + results_df.loc[iter, 'total_tax']) + ','
        log += str(results_df.loc[iter, 'cash']) + '\n'
        #         log += str(x.total_commission + x.total_tax) + '\n'
        f_total.write(log)
    # portfolio = results_df.loc[iter, 'portfolio']
    #         for d, x in portfolio.items():
    #             log = str(iter) + ','
    #             log = str(x.portfolio_value) + ','
    #             log = str(x.cash) + ','
    #             log = str(x.total_commission + x.total_tax) + '\n'
    #

    fsock.close()
    f_position.close()
    f_total.close()


def update_strategy(userid, strategyid):
    query_set = models.UpQuantUserStrategyListInfo.objects.get(userid=userid,
                                                               strategyid=strategyid)
    query_set.modifytime = datetime.datetime.now()
    print userid, query_set.modifytime, strategyid
    query_set.state = 0
    query_set.num += 1
    query_set.save()

    return 1


def get_position_detail(data, session):
    userid = session['userId']
    strategyid = session['strategyId']
    versionid = session['versionId']
    index = int(data['index'])
    filename = 'runlog/'
    filename += userid + '_' + strategyid + '_' + versionid + '.csv.position'
    total_filename = 'runlog/'
    total_filename += userid + '_' + strategyid + '_' + versionid + '.csv.total'

    if (not os.path.exists(filename)) or (not os.path.exists(total_filename)):
        return {'userId': userid,
                'pageCount': 0,
                'strategyId': strategyid,
                'versionId': versionid,
                'index': index,
                'returnList': []}
    reader = csv.reader(open(filename, 'r'))
    total_reader = csv.reader(open(total_filename, 'r'))
    temp_list = []
    cur_item = [0, 0, 0, 0]
    for item in reader:
        date = str(item[0])[0:10]
        for total_item in total_reader:
            if date == str(total_item[0])[0:10]:
                cur_item = total_item
                break
        temp_list.append({'date': date,
                          'stockID': str(item[1]),
                          'closePrice': str(round(float(item[5]), 2)),
                          'stockNum': str(item[3]),
                          'positionValue': str(round(float(item[2]), 3)),
                          'return': str(item[6]),
                          'commissionValue': str(item[4]),
                          'stockName': str(item[7]),
                          'totalValue': str(round(float(cur_item[1]), 2)),
                          'totalCash': str(round(float(cur_item[3]), 2)),
                          'totalCommission': str(round(float(cur_item[2]), 2))})

    return {'userId': userid,
            'pageCount': paging.get_page_count(temp_list, 8),
            'strategyId': strategyid,
            'versionId': versionid,
            'index': index,
            'returnList': paging.get_page_list(index, temp_list, 8)}


def get_runlog_filename(session_info):
    filename = 'runlog/'
    filename += str(session_info["userid"]) + "_"
    filename += str(session_info["strategyid"]) + "_"
    filename += str(session_info["versionid"]) + ".csv"
    return filename


def get_session_filename(session_info):
    filename = 'log/'
    filename += str(session_info["userid"]) + "_"
    filename += str(session_info["strategyid"]) + "_"
    filename += str(session_info["versionid"]) + ".log"
    return filename


def get_session_log(session_info):
    filename = get_session_filename(session_info)
    if os.path.exists(filename) is not True:
        return ""
    with open(filename, 'r') as f_log_file:
        context = f_log_file.readlines()
        return context
    return ""


def helloQuant(codecontext, startTime, endTime, init_cash, session_info):
    saveout = sys.stdout
    filename = get_session_filename(session_info)
    fsock = open(filename, 'w')
    # 为了避免用户连续点击操作，频繁打开相同的此文件，所以对此文件加锁
    fcntl.flock(fsock, fcntl.LOCK_EX)
    fsock.truncate()
    # sys.stdout = fsock
    results_df = None
    logerr = []
    errtype = 0
    try:
        results_df = run(codecontext, pd.Timestamp(startTime), pd.Timestamp(endTime), init_cash)
        sys.stdout = saveout
        fsock.close()
    except RuntimeError, e:
        err = e.args
        logerr.append(err)
        errtype = 1
        sys.stdout = saveout
        fsock.close()
        return {'total_returns': [], 'benchmarkReturn': [], 'totalinfo': [], 'errlog': logerr, 'errtype': errtype}
    except:
        lines = traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1])
        for line in lines:
            logerr.append(line)
        errtype = 2
        sys.stdout = saveout
        fsock.close()
        return {'total_returns': [], 'benchmarkReturn': [], 'totalinfo': [], 'errlog': logerr, 'errtype': errtype}
    try:
        resultlogname = get_runlog_filename(session_info)
        info = UpQuantBktestSumInfo()
        info.strategyid = session_info["strategyid"]
        info.versionid = session_info["versionid"]
        userid = session_info["userid"]
        getTotalInfo(info, results_df, startTime, endTime, init_cash)
        sys.stdout = saveout
        saveUpQuantBktestSumInfo(info)
        saveUpQuantContext(info, codecontext, startTime, endTime, init_cash)
        saveUpQuantTradeInfo(info, results_df)
        saveUPTradeLogInfo(resultlogname, results_df)
        update_strategy(userid, info.strategyid)
        totalReturn = []
        benchmarkReturn = []
        for date in results_df["total_returns"].index:
            timeArray = time.strptime(str(date), "%Y-%m-%d %H:%M:%S")
            timeStamp = int(time.mktime(timeArray)) * 1000
            temp1 = [timeStamp, round(results_df["total_returns"][date], 4) * 100]

            totalReturn.append(temp1)
            temp2 = [timeStamp, round(results_df["benchmark_total_returns"][date], 4) * 100]
            benchmarkReturn.append(temp2)
    except:
        return {'total_returns': [], 'benchmarkReturn': [], 'totalinfo': [], 'errlog': [], 'errtype': []}

    return {'total_returns': totalReturn, 'benchmarkReturn': benchmarkReturn, 'totalinfo': info, 'errlog': logerr,
            'errtype': errtype}


def get_new_version_id(session):
    query_set = models.UpQuantBktestSumInfo.objects.filter(strategyid=session['strategyId']).order_by('-versionid')
    if len(query_set) == 0:
        return 0
    for temp in query_set.values():
        old_version = temp['versionid']
        break
    return int(old_version)


def pre_compile(code_context):
    code_context = code_context.lower()
    str_result = code_context.replace(' ', '')
    if 'importos' in str_result:
        return False
    if 'importshutil' in str_result:
        return False
    if 'importglob' in str_result:
        return False
    if 'importsubprocess' in str_result:
        return False
    if 'importsys' in str_result:
        return False
    if 'importthreading' in str_result:
        return False
    if 'importmultiprocessing' in str_result:
        return False
    if 'importsocket' in str_result:
        return False
    if 'importsocketServer' in str_result:
        return False
    if 'importasyncore' in str_result:
        return False
    if 'importrequest' in str_result:
        return False
    if 'importresponce' in str_result:
        return False
    if 'importBaseHTTPServer' in str_result:
        return False
    if 'importurllib' in str_result:
        return False
    if 'importurllib2' in str_result:
        return False
    if 'importurlparse' in str_result:
        return False
    if 'importcommands' in str_result:
        return False
    return True

'''执行策略回测的接口'''


def exec_strategy(data, session):
    userid = session['userId']
    strategyid = session['strategyId']
    versionid = session['versionId']
    codeContext = data['codeContext']
    start_date = data['beginTime']
    end_date = data['endTime']
    intCash = data['intCash']
    b_back_test = data['back_test']
    print userid, strategyid, versionid
    if b_back_test == '1':
        versionid = get_new_version_id(session) + 1
        versionid = str(versionid)
        session['versionId'] = versionid

    session_inf0 = {"userid": userid, "strategyid": strategyid, "versionid": versionid}
    if pre_compile(codeContext) is False:
        result = {
            'totalReturn': 0,
            'benchmarkReturn': 0,
            'annualReturn': 0,
            'totalReturnList': [],
            'benchmarkReturnList': [],
            'errLog': [u'不要瞎搞事'],
            'errType': '1'
        }
        json_str = json.dumps(result)
        return json_str
    info = helloQuant(codeContext, start_date, end_date, int(intCash), session_inf0)
    totalinfo = info['totalinfo']
    if totalinfo:
        total_returns_list = info['total_returns']
        benchmark_return_list = info['benchmarkReturn']
        result = {
            'totalReturn': round(totalinfo.totalreturn, 4),
            'benchmarkReturn': round(totalinfo.benchmark, 4),
            'annualReturn': round(totalinfo.myannualreturn, 4),
            'totalReturnList': total_returns_list,
            'benchmarkReturnList': benchmark_return_list,
            'errLog': info['errlog'],
            'errType': info['errtype']
        }
        json_str = json.dumps(result)

        return json_str
    else:
        result = {
            'totalReturn': 0,
            'benchmarkReturn': 0,
            'annualReturn': 0,
            'totalReturnList': [],
            'benchmarkReturnList': [],
            'errLog': info['errlog'],
            'errType': info['errtype']
        }
        json_str = json.dumps(result)
        return json_str


'''执行存储代码的接口'''


def save_strategy(data, session):
    try:
        user_id = session['userId']
        strategyid = session['strategyId']
        versionid = session['versionId']
        codecontext = data['codeContext']
        begin_date = data['beginDate']
        end_date = data['endDate']
        int_cash = data['intCash']
        strategy_name = data['strategyName']

        quantContext, state = UpQuantStrategyContex.objects.get_or_create(strategyid=strategyid,
                                                                          versionid=versionid)
        quantContext.strategyid = strategyid
        quantContext.versionid = versionid
        quantContext.context = codecontext
        quantContext.begindate = str(begin_date).replace('/', '-')
        quantContext.enddate = str(end_date).replace('/', '-')
        quantContext.initcash = int_cash
        quantContext.save()

        query_user = models.UpQuantUserStrategyListInfo.objects.get(strategyid=strategyid, userid=user_id)
        query_user.name = strategy_name
        query_user.save()
        session["strategyName"] = strategy_name
        return 1
    except Exception, e:
        print str(e) + 'is error'
        return 0


def get_return_info(data, session):
    userid = session['userId']
    strategyid = session['strategyId']
    versionid = session['versionId']

    queryset = models.UpQuantBktestSumInfo.objects.filter(strategyid=strategyid, versionid=versionid)
    for temp in queryset.values():
        result_dict = {'benchmarkReturn': temp['benchmark'], 'totalReturn': temp['totalreturn'],
                       'annualreturn': temp['myannualreturn'], 'benchmarkAnnualReturn': temp['benchmarkannualreturn'],
                       'alpha': temp['alpha'], 'beta': temp['beta'], 'sharpe': temp['sharpe'],
                       'inforatio': temp['inforatio'],
                       'sortino': temp['sortino'], 'volatility': temp['volatility'], 'maxDrewdown': temp['maxdrewdown'],
                       'trackingerror': temp['trackingerror'], 'downsiderisk': temp['downsiderisk']}

    filename = 'runlog/'
    filename += userid + '_' + strategyid + '_' + versionid + '.csv'
    if os.path.exists(filename) is not True:
        return {'totalReturnList': [], 'benchmarkReturnList': []}
    reader = csv.reader(open(filename, 'r'))
    temp_return_list = []
    temp_benchmark_list = []
    for item in reader:
        timeArray = time.strptime(str(item[0]), "%Y-%m-%d %H:%M:%S")
        timeStamp = int(time.mktime(timeArray)) * 1000
        temp_return_list.append([timeStamp, float(item[1]) * 100])
        temp_benchmark_list.append([timeStamp, float(item[3]) * 100])
    result_dict['totalReturnList'] = temp_return_list
    result_dict['benchmarkReturnList'] = temp_benchmark_list
    return result_dict


def get_strategy_info(data, session):
    try:
        userid = session['userId']
        strategyid = session['strategyId']
        versionid = session['versionId']
        queryset = models.UpQuantBktestSumInfo.objects.get(strategyid=strategyid, versionid=versionid)
    except Exception, e:
        return ""
    return queryset


def get_trade_detail(data, session):
    userid = session['userId']
    strategyid = session['strategyId']
    versionid = session['versionId']

    queryset = models.UpQuantTradeinfo.objects.filter(strategyid=strategyid, versionid=versionid)
    result_list = []
    transaction = 0
    sell_vol = 0.0
    buy_vol = 0.0
    for temp in queryset.values():
        ordercount = temp['ordercount']
        if ordercount is None:
            ordercount = 0
        result_list.append(
            {'orderdate': str(temp['orderdate']), 'ordertime': str(temp['ordertime'])[0:8], 'price': temp['price'],
             'orderstate': temp['orderstate'],
             'stockcode': temp['stockcode'], 'stockname': temp['stockname'],
             'ordercount': ordercount,
             'price': temp['price'], 'totalcost': temp['totalcost'], 'commission': temp['commission']})
        transaction += 1
        if int(temp['orderstate']) > 0:
            buy_vol += float(temp['price']) * float(ordercount)
        else:
            sell_vol += float(temp['price']) * float(ordercount)
    return result_list, transaction, buy_vol, sell_vol


def get_history_detail(data, col, session):
    userid = session.get('userId', None)
    if userid is None:
        return {}
    strategyid = session['strategyId']
    versionid = session['versionId']
    index = int(data['index'])
    filename = 'runlog/'
    filename += userid + '_' + strategyid + '_' + versionid + '.csv'

    if os.path.exists(filename) is not True:
        return {'userId': userid,
                'strategyId': strategyid,
                'versionId': versionid,
                'pageCount': 0,
                'index': index,
                'returnList': []}

    reader = csv.reader(open(filename, 'r'))

    temp_list = []
    pre_date = ''
    pre_context = ''
    for item in reader:
        date = item[0][0:7]  # 取每月的最后一天
        if date != pre_date:
            if pre_date != "":
                temp_list.append({'date': pre_date, 'context': pre_context})

        pre_date = date
        pre_context = str(item[col])
    if pre_date != "":
        temp_list.append({'date': pre_date, 'context': pre_context})

    return {'userId': userid,
            'strategyId': strategyid,
            'versionId': versionid,
            'pageCount': paging.get_page_count(temp_list, 10),
            'index': index,
            'returnList': paging.get_page_list(index, temp_list, 10)}


def get_history_code(data, session):
    strategy_id = session['strategyId']
    version_id = data['versionId']

    queryset = models.UpQuantStrategyContex.objects.get(strategyid=strategy_id, versionid=version_id)
    return {'codeContext': queryset.context}


def format_datetime(data):
    time_str = str(data)[0: 19].replace('T', ' ')
    return time_str


def get_strategy_list(data, session):

    user_id = session.get('userId', None)
    if user_id is None:
        return {""}
    result_lsit = []
    queryset = models.UpQuantUserStrategyListInfo.objects.filter(userid=user_id).order_by('-createtime')
    for user in queryset.values():
        if user['state'] != 0:
            continue
        strategyid = user['strategyid']
        queryset_t = models.UpQuantBktestSumInfo.objects.filter(strategyid=strategyid).order_by('-versionid')
        if queryset_t.count() == 0:
            result_lsit.append({
                'strategyId': strategyid,
                'versionId': 1,
                'strategyName': user['name'],
                'createTime': format_datetime(user['createtime']),
                'modifyTime': format_datetime(user['modifytime']),
                'backtestHistory': 0,
                'simulateHistory': 0,
                'earnings': 0,
                'alpaha': 0,
                'beta': 0,
                'sharp': 0,
                'volatility': 0,
                'MaxDrawdown': 0,
            })
        else:
            for strategy in queryset_t.values():
                result_lsit.append({'strategyId': strategyid,
                                    'versionId': strategy['versionid'],
                                    'strategyName': user['name'],
                                    'createTime': format_datetime(user['createtime']),
                                    'modifyTime': format_datetime(user['modifytime']),
                                    'backtestHistory': len(queryset_t),
                                    'simulateHistory': 0,
                                    'earnings': strategy['totalreturn'],
                                    'alpaha': strategy['alpha'],
                                    'beta': strategy['beta'],
                                    'sharp': strategy['sharpe'],
                                    'volatility': strategy['volatility'],
                                    'MaxDrawdown': strategy['maxdrewdown']})
                break
    index = int(data['index'])
    return {'userId': user_id, 'pageCount': paging.get_page_count(result_lsit, 5), 'index': index,
            'StrategyList': paging.get_page_list(index, result_lsit, 5)}


def new_strategy(data, session):
    userid = session.get('userId', None)
    if userid is None:
        return 0
    strategyid = userid + '_' + str(time.time()) + '_' + str(random.randint(0, 10000))
    strategyname = data['strategyName']
    createtime = data['createTime']
    modifytime = data['modifyTime']

    query_set, state = models.UpQuantUserStrategyListInfo.objects.get_or_create(userid=userid,
                                                                                strategyid=strategyid)
    query_set.name = strategyname
    query_set.createtime = createtime
    query_set.modifytime = modifytime
    query_set.state = 0
    query_set.num = 0
    query_set.save()

    quantContext, state = UpQuantStrategyContex.objects.get_or_create(strategyid=strategyid,
                                                                      versionid=0)
    quantContext.strategyid = strategyid
    quantContext.versionid = 1
    quantContext.context = '# 可以自己import我们平台支持的第三方python模块，比如pandas、numpy等。\n\n\
# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。\n\
def init(context):\n\
    context.s1 = "000001.XSHE"\n\
    # 是否已发送了order\n\
    context.fired = False\n\n\
# 你选择的证券的数据更新将会触发此段逻辑，例如日或分钟历史数据切片或者是实时数据切片更新\n\
def handle_bar(context, bar_dict):\n\
    # 开始编写你的主要的算法逻辑\n\n\
    # bar_dict[order_book_id] 可以拿到某个证券的bar信息\n\
    # context.portfolio 可以拿到现在的投资组合状态信息\n\n\
    # 使用order_shares(id_or_ins, amount)方法进行落单\n\n\
    # TODO: 开始编写你的算法吧！\n\
    if not context.fired:\n\
        # order_percent并且传入1代表买入该股票并且使其占有投资组合的100%\n\
        order_percent(context.s1, 1)\n\
        context.fired = True'

    quantContext.begindate = '2015-01-05'
    quantContext.enddate = '2016-01-05'
    quantContext.initcash = 100000
    quantContext.save()

    return {'strategyid': strategyid, 'versionid': 1}


def del_strategy(request):
    strategy_id = request.data['strategyId']

    if strategy_id is None:
        return 0
    else:
        user_id = request.session["userId"]
        queryset = models.UpQuantUserStrategyListInfo.objects.get(userid=user_id, strategyid=strategy_id)
        queryset.state = 1
        queryset.save()

    return 1


def copy_strategy(data, session):
    user_id = session['userId']
    strategyId = user_id + '_' + str(time.time()) + '_' + str(random.randint(0, 10000))
    context = data['codeContext']
    strategy_name = data['strategyName']
    begin_time = data['beginDate']
    end_time = data['endDate']
    int_cash = data['intCash']

    query_set, state = models.UpQuantUserStrategyListInfo.objects.get_or_create(userid=user_id,
                                                                                strategyid=strategyId)
    query_set.name = u'复制策略_' + strategy_name
    query_set.createtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
    query_set.modifytime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
    query_set.state = 0
    query_set.num = 0
    query_set.save()

    quantContext, state = UpQuantStrategyContex.objects.get_or_create(strategyid=strategyId,
                                                                      versionid=0)
    quantContext.strategyid = strategyId
    quantContext.versionid = 1
    quantContext.context = context

    quantContext.begindate = str(begin_time).replace('/', '-')
    quantContext.enddate = str(end_time).replace('/', '-')
    quantContext.initcash = int(int_cash)
    quantContext.save()

    session['strategyId'] = strategyId
    session['versionId'] = quantContext.versionid
    return {'state': '1', 'strategyId': strategyId, 'versionId': quantContext.versionid}


def get_history_result(data, session):
    version_id = data['versionId']
    session['versionId'] = version_id
    return {'state': '1'}


def output_log(data, session):
    user_id = session['userId']
    strategy_id = session['strategyId']
    version_id = session['versionId']

    filename = 'log/'
    filename += user_id + "_" + strategy_id + "_" + version_id + ".log"

    if os.path.exists(filename) is not True:
        return {"userId": user_id, "strategyId": strategy_id, "versionId": version_id, "logList": ""}
    with open(filename) as f:
        result_str = f.readlines()
    return {"userId": user_id, "strategyId": strategy_id, "versionId": version_id, "logList": result_str}


def get_back_test_history(data, session):
    user_id = session['userId']
    strategy_id = session['strategyId']
    if str(data['beginTime']) != '0' and str() != '0':
        str_begin_time = str(data['beginTime']).replace('/', '-')
        str_begin_time += ' 00:00:00'
        begin_time = datetime.datetime.strptime(str_begin_time, "%Y-%m-%d %H:%M:%S")
        str_end_time = str(data['endTime']).replace('/', '-')
        str_end_time += ' 23:59:59'
        end_time = datetime.datetime.strptime(str_end_time, "%Y-%m-%d %H:%M:%S")
        query_set = models.UpQuantStrategyContex.objects.filter(strategyid=strategy_id,
                                                                createtime__range=[begin_time, end_time]).order_by('-versionid')
    else:
        query_set = models.UpQuantStrategyContex.objects.filter(strategyid=strategy_id).order_by('-versionid')
    return_list = []
    i = 1
    for his in query_set.values():
        version_id = his['versionid']
        try:
            temp = UpQuantBktestSumInfo.objects.get(strategyid=strategy_id, versionid=version_id)
        except Exception, e:
            continue
        return_list.append({'index': str(i),
                            'versionId': version_id,
                            'createTime': format_datetime(his['createtime']),
                            'beginTime': his['begindate'],
                            'endTime': his['enddate'],
                            'intCash': his['initcash'],
                            'totalReturn': temp.totalreturn
                            })
        i += 1
    index = int(data['index'])
    return {'userId': user_id, 'strategyId': strategy_id,
            'pageCount': paging.get_page_count(return_list, 10),
            'index': index,
            'backTestList': paging.get_page_list(index, return_list, 10)}


def get_kline_data():
    client = redis.Redis(host='120.55.149.71',
                         port=16379, db=0, password='redisserver')

    kline_data = client.zrevrangebyscore('KX:HISDAYKLINE:00000000010000000000000000000000', 20160902, 20160101)

    result_list = []
    for kline in kline_data:
        tmp = str(kline)
        new = tmp[:-1]
        tmplist = new.split(' ', len(tmp))
        result_list.append({
            'Date': tmplist[0],
            'open': float(tmplist[1]),
            'high': float(tmplist[2]),
            'low': float(tmplist[3]),
            'close': float(tmplist[4]),
            'volume': float(tmplist[6])
        })
    return result_list
